home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / bsvc-1.000 / bsvc-1 / bsvc-1.0.4 / src / SimHector / cpu / exec.cxx < prev    next >
C/C++ Source or Header  |  1995-07-26  |  81KB  |  2,580 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. //   File:        exec.cxx  (Part of the ControlUnit Class)
  4. //
  5. //   Purpose:     This module contains the instruction execution       
  6. //                functions.  Each function does address mode decoding 
  7. //                where necessary and then calls the appropriate      
  8. //                register transfer functions to execute the        
  9. //                instruction.  The comments above each register     
  10. //                transfer function call are the actual HECTOR        
  11. //                microcode instructions performed.                   
  12. //                                                                   
  13. //                NOTE: Because these instructions follow the micro-   
  14. //                code, they also depend on such things as the fact  
  15. //                that in single operand instructions like SWAP the     
  16. //                SRC and DST fields in the instruction both contain    
  17. //                the operand register                                 
  18. //                                                                      
  19. //   Author:      Greg DeHoogh
  20. //
  21. //   Modified:    Bradford W. Mott (BSVC version)
  22. //                                                                      
  23. //   History:     17 February 1990 - Creation                           
  24. //                                                                      
  25. //                18 April 1990 - fixed bug in group1, source mode     
  26. //                   indexed, destination mode postincrement - GLD      
  27. //                                                                      
  28. //                24 April 1990 - fixed bug in move, source and       
  29. //                   destination modes indexed; and in group1, source  
  30. //                   mode indirect and desination mode postincrement
  31. //                   - GLD
  32. //
  33. //                04 December 1993 - Modified to work with the new
  34. //                   BSVC version of the Hector simulator
  35. //
  36. ///////////////////////////////////////////////////////////////////////////////
  37.  
  38. #include "Tools.hxx"
  39. #include "ControlUnit.hxx"
  40.  
  41. ///////////////////////////////////////////////////////////////////////////////
  42. // Addressing Modes
  43. ///////////////////////////////////////////////////////////////////////////////
  44. const unsigned int REG=0;    // Register Direct
  45. const unsigned int IND=1;    // Register Indirect 
  46. const unsigned int ABS=1;    // Absolute (used by BRA and JSR)
  47. const unsigned int INC=2;    // Register Indirect with postincrement
  48. const unsigned int REL=2;    // Program Counter Relative (BRA and JSR)
  49. const unsigned int NDX=3;    // Indexed
  50.  
  51. ///////////////////////////////////////////////////////////////////////////////
  52. // group1 - ADD, ADDC, SUB, AND, SUBC, OR, and XOR
  53. ///////////////////////////////////////////////////////////////////////////////
  54. const char* ControlUnit::ExecuteGroup1(int trace_flag)
  55. {
  56.    int DM  = (data_path.ir & 0x0300) >> 8;
  57.    int SM  = (data_path.ir & 0x0c00) >> 10;
  58.    int SRC = (data_path.ir &0x00f0) >> 4;
  59.    int DST = (data_path.ir &0x000f);
  60.    const char*  error_message;
  61.    unsigned int src_index, dst_index;
  62.  
  63.    switch(DM)
  64.    {
  65.      case REG: switch(SM) {
  66.          case REG:                  // OP Rsrc,Rdst
  67.            // dst < dst OP src
  68.            if((error_message = reg_op_reg_to_reg(SRC, DST)) != (void*)0)
  69.              return(error_message);
  70.  
  71.            if(trace_flag)
  72.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  73.            break;
  74.  
  75.          case IND:                  // OP [Rsrc],Rdst
  76.            // t1 < (src)
  77.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  78.              return(error_message);
  79.  
  80.            // dst < dst OP t1
  81.            if((error_message = reg_op_reg_to_reg(T1, DST)) != (void*)0)
  82.              return(error_message);
  83.  
  84.            if(trace_flag)
  85.            {
  86.              mnemonic+="[";
  87.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  88.              mnemonic+="]";
  89.            }
  90.            break;
  91.  
  92.          case INC:                  // OP [Rsrc+],Rdst
  93.            // t1 < (src)
  94.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  95.              return(error_message);
  96.  
  97.            // src < src + 1
  98.            if((error_message = inc_reg(SRC)) != (void*)0)
  99.              return(error_message);
  100.  
  101.            // dst < dst OP t1
  102.            if((error_message = reg_op_reg_to_reg(T1, DST)) != (void*)0)
  103.              return(error_message);
  104.  
  105.            if(trace_flag)
  106.            {
  107.              mnemonic+="[";
  108.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  109.              mnemonic+="+]";
  110.            }
  111.            break;
  112.  
  113.          case NDX:                  // OP [Rsrc,index],Rdst
  114.            // t1 < (pc)
  115.            if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  116.              return(error_message);
  117.  
  118.            // Save the index to put in trace record
  119.            src_index=data_path.register_set.GetRegister(T1);
  120.  
  121.            // pc < pc + 1
  122.            if((error_message = inc_reg(PC)) != (void*)0)
  123.              return(error_message);
  124.  
  125.            // mar < t1 + src
  126.            if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  127.              return(error_message);
  128.  
  129.            // t1 < (mar)
  130.            if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
  131.              return(error_message);
  132.  
  133.            // dst < dst OP t1 
  134.            if((error_message = reg_op_reg_to_reg(T1, DST)) != (void*)0)
  135.              return(error_message);
  136.  
  137.            if(trace_flag)
  138.            {
  139.              mnemonic+="[";
  140.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  141.              mnemonic+=",$";
  142.              mnemonic+=IntToString(src_index, 4);
  143.              mnemonic+="]";
  144.            }
  145.            break;
  146.          }
  147.  
  148.          if(trace_flag)
  149.          {
  150.            mnemonic+=",";
  151.            mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  152.          }
  153.          break;
  154.  
  155.       case IND: switch (SM) {
  156.          case REG:                  // OP Rsrc,[Rdst]
  157.            // t2 < (dst)
  158.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  159.              return(error_message);
  160.  
  161.            // mdr < t2 OP src
  162.            if((error_message = reg_op_reg_to_mdr(SRC, T2)) != (void*)0)
  163.              return(error_message);
  164.  
  165.            // (mar) < mdr
  166.            if((error_message = mdr_to_mar_indirect()) != (void*)0)
  167.              return(error_message);
  168.  
  169.            if(trace_flag)
  170.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  171.            break;
  172.  
  173.          case IND:                  // OP [Rsrc],[Rdst]
  174.            // t1 < (src)
  175.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  176.              return(error_message);
  177.  
  178.            // t2 < (dst)
  179.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  180.              return(error_message);
  181.  
  182.            // mdr < t2 OP t1 
  183.            if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
  184.              return(error_message);
  185.  
  186.            // (mar) < mdr
  187.            if((error_message = mdr_to_mar_indirect()) != (void*)0)
  188.              return(error_message);
  189.  
  190.            if(trace_flag)
  191.            {
  192.              mnemonic+="[";
  193.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  194.              mnemonic+="]";
  195.            }
  196.            break;
  197.  
  198.          case INC:                  // OP [Rsrc+],[Rdst]
  199.            // t1 < (src)
  200.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  201.              return(error_message);
  202.  
  203.            // src < src + 1
  204.            if((error_message = inc_reg(SRC)) != (void*)0)
  205.              return(error_message);
  206.  
  207.            // t2 < (dst)
  208.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  209.              return(error_message);
  210.  
  211.            // mdr < t2 OP t1
  212.            if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
  213.              return(error_message);
  214.  
  215.            // (mar) < mdr */
  216.            if((error_message = mdr_to_mar_indirect()) != (void*)0)
  217.              return(error_message);
  218.  
  219.            if(trace_flag)
  220.            {
  221.              mnemonic+="[";
  222.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  223.              mnemonic+="+]";
  224.            }
  225.            break;
  226.  
  227.          case NDX:                  // OP [Rsrc,index],[Rdst]
  228.            // t1 < (pc)
  229.            if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  230.              return(error_message);
  231.  
  232.            // Save the index to put the in the trace record
  233.            src_index=data_path.register_set.GetRegister(T1);
  234.  
  235.            // pc < pc + 1
  236.            if((error_message = inc_reg(PC)) != (void*)0)
  237.              return(error_message);
  238.  
  239.            // mar < t1 + src
  240.            if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  241.              return(error_message);
  242.  
  243.            // t1 < (mar)
  244.            if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
  245.              return(error_message);
  246.  
  247.            // t2 < (dst)
  248.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  249.              return(error_message);
  250.  
  251.            // mdr < t2 * t1
  252.            if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
  253.              return(error_message);
  254.  
  255.            // (mar) < mdr
  256.            if((error_message = mdr_to_mar_indirect()) != (void*)0)
  257.              return(error_message);
  258.  
  259.            if(trace_flag)
  260.            {
  261.              mnemonic+="[";
  262.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  263.              mnemonic+=",$";
  264.              mnemonic+=IntToString(src_index, 4);
  265.              mnemonic+="]";
  266.            }
  267.            break;
  268.          }
  269.  
  270.          if(trace_flag)
  271.          {
  272.            mnemonic+=",[";
  273.            mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  274.            mnemonic+="]";
  275.          }
  276.          break;
  277.  
  278.       case INC: switch (SM) {
  279.          case REG:                  // OP Rsrc,[Rdst+]
  280.            // t2 < (dst)
  281.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  282.              return(error_message);
  283.  
  284.            // mdr < t2 OP src
  285.            if((error_message = reg_op_reg_to_mdr(SRC, T2)) != (void*)0)
  286.              return(error_message);
  287.  
  288.            // (mar) < mdr; dst < dst + 1
  289.            if((error_message = mdr_to_mar_indirect_with_inc(DST)) != (void*)0)
  290.              return(error_message);
  291.  
  292.            if(trace_flag)
  293.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  294.            break;
  295.  
  296.          case IND:                  // OP [Rsrc],[Rdst+]
  297.            // t1 < (src) 
  298.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  299.              return(error_message);
  300.  
  301.            // t2 < (dst)
  302.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  303.              return(error_message);
  304.  
  305.            // mdr < t2 OP t1
  306.            if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
  307.              return(error_message);
  308.  
  309.            // (mar) < mdr; dst < dst + 1 
  310.            if((error_message = mdr_to_mar_indirect_with_inc(DST)) != (void*)0)
  311.              return(error_message);
  312.  
  313.            if(trace_flag)
  314.            {
  315.              mnemonic+="[";
  316.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  317.              mnemonic+="]";
  318.            }
  319.            break;
  320.  
  321.          case INC:                  // OP [Rsrc+],[Rdst+]
  322.            // t1 < (src)
  323.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  324.              return(error_message);
  325.  
  326.            // src < src + 1
  327.            if((error_message = inc_reg(SRC)) != (void*)0)
  328.              return(error_message);
  329.  
  330.            // t2 < (dst)
  331.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  332.              return(error_message);
  333.  
  334.            // mdr < t2 OP t1 
  335.            if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
  336.              return(error_message);
  337.  
  338.            // (mar) < mdr; dst < dst + 1
  339.            if((error_message = mdr_to_mar_indirect_with_inc(DST)) != (void*)0)
  340.              return(error_message);
  341.  
  342.            if(trace_flag)
  343.            {
  344.              mnemonic+="[";
  345.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  346.              mnemonic+="+]";
  347.            }
  348.            break;
  349.  
  350.          case NDX:                  // OP [Rsrc,index],[Rdst+]
  351.            // t1 < (pc)
  352.            if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  353.              return(error_message);
  354.  
  355.            // Save the index to put the in the trace record
  356.            src_index=data_path.register_set.GetRegister(T1);
  357.  
  358.            // pc < pc + 1
  359.            if((error_message = inc_reg(PC)) != (void*)0)
  360.              return(error_message);
  361.  
  362.            // mar < t1 + src
  363.            if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  364.              return(error_message);
  365.  
  366.            // t1 < (mar)
  367.            if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
  368.              return(error_message);
  369.  
  370.            // t2 < (dst)
  371.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  372.              return(error_message);
  373.  
  374.            // mdr < t2 OP t1
  375.            if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
  376.              return(error_message);
  377.  
  378.            // (mar) < mdr; dst < dst + 1
  379.            if((error_message = mdr_to_mar_indirect_with_inc(DST)) != (void*)0)
  380.              return(error_message);
  381.  
  382.            if(trace_flag)
  383.            {
  384.              mnemonic+="[";
  385.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  386.              mnemonic+=",$";
  387.              mnemonic+=IntToString(src_index, 4);
  388.              mnemonic+="]";
  389.            }
  390.            break;
  391.          }
  392.  
  393.          if(trace_flag)
  394.          {
  395.            mnemonic+=",[";
  396.            mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  397.            mnemonic+="+]";
  398.          }
  399.          break;
  400.  
  401.       case NDX: switch (SM) {
  402.          case REG:                  // OP Rsrc,[Rdst,index]
  403.            // t2 < (pc)
  404.            if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
  405.              return(error_message);
  406.  
  407.            // Save index value to build trace record with
  408.            dst_index=data_path.register_set.GetRegister(T2);
  409.  
  410.            // mar < t2 + dst
  411.            if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
  412.              return(error_message);
  413.  
  414.            // t2 < (mar)
  415.            if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
  416.              return(error_message);
  417.  
  418.            // mdr < t2 OP src
  419.            if((error_message = reg_op_reg_to_mdr(SRC, T2)) != (void*)0)
  420.              return(error_message);
  421.  
  422.            // (mar) < mdr; pc < pc + 1
  423.            if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
  424.              return(error_message);
  425.  
  426.            if(trace_flag)
  427.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  428.            break;
  429.  
  430.          case IND:                  // OP [Rsrc],[Rdst,index]
  431.            // t1 < (src)
  432.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  433.              return(error_message);
  434.  
  435.            // t2 < (pc)
  436.            if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
  437.              return(error_message);
  438.  
  439.            // Save index value to build trace record with
  440.            dst_index=data_path.register_set.GetRegister(T2);
  441.  
  442.            // mar < t2 + dst
  443.            if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
  444.              return(error_message);
  445.  
  446.            // t2 < (mar)
  447.            if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
  448.              return(error_message);
  449.  
  450.            // mdr < t2 OP t1
  451.            if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
  452.              return(error_message);
  453.  
  454.            // (mar) < mdr; pc < pc + 1
  455.            if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
  456.              return(error_message);
  457.  
  458.            if(trace_flag)
  459.            {
  460.              mnemonic+="[";
  461.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  462.              mnemonic+="]";
  463.            }
  464.            break;
  465.  
  466.          case INC:                  // OP [Rsrc+],[Rdst,index]
  467.            // t1 < (src)
  468.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  469.              return(error_message);
  470.  
  471.            // src < src + 1
  472.            if((error_message = inc_reg(SRC)) != (void*)0)
  473.              return(error_message);
  474.  
  475.            // t2 < (pc)
  476.            if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
  477.              return(error_message);
  478.  
  479.            // Save index value to build trace record with
  480.            dst_index=data_path.register_set.GetRegister(T2);
  481.  
  482.            // mar < t2 + dst
  483.            if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
  484.              return(error_message);
  485.  
  486.            // t2 < (mar)
  487.            if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
  488.              return(error_message);
  489.  
  490.            // mdr < t2 OP t1
  491.            if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
  492.              return(error_message);
  493.  
  494.            // (mar) < mdr; pc < pc + 1
  495.            if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
  496.              return(error_message);
  497.  
  498.            if(trace_flag)
  499.            {
  500.              mnemonic+="[";
  501.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  502.              mnemonic+="+]";
  503.            }
  504.            break;
  505.  
  506.          case NDX:                  // OP [Rsrc,index],[Rdst,index]
  507.            // t1 < (pc)
  508.            if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  509.              return(error_message);
  510.  
  511.            // Save index value to build trace record with
  512.            src_index=data_path.register_set.GetRegister(T1);
  513.  
  514.            // pc < pc + 1
  515.            if((error_message = inc_reg(PC)) != (void*)0)
  516.              return(error_message);
  517.  
  518.            // mar < t1 + src
  519.            if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  520.              return(error_message);
  521.  
  522.            // t1 < (mar)
  523.            if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
  524.              return(error_message);
  525.  
  526.            // t2 < (pc)
  527.            if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
  528.              return(error_message);
  529.  
  530.            // Save index value to build trace record with
  531.            dst_index=data_path.register_set.GetRegister(T2);
  532.  
  533.            // mar < t2 + dst
  534.            if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
  535.              return(error_message);
  536.  
  537.            // t2 < (mar)
  538.            if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
  539.              return(error_message);
  540.  
  541.            // mdr < t2 OP t1
  542.            if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
  543.              return(error_message);
  544.  
  545.            // (mar) < mdr; pc < pc + 1
  546.            if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
  547.              return(error_message);
  548.  
  549.            if(trace_flag)
  550.            {
  551.              mnemonic+="[";
  552.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  553.              mnemonic+=",$";
  554.              mnemonic+=IntToString(src_index, 4);
  555.              mnemonic+="]";
  556.            }
  557.            break;
  558.          }
  559.  
  560.          if(trace_flag)
  561.          {
  562.            mnemonic+=",[";
  563.            mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  564.            mnemonic+=",$";
  565.            mnemonic+=IntToString(dst_index, 4);
  566.            mnemonic+="]";
  567.          }
  568.    }
  569.    return((void*)0);
  570. }
  571.  
  572. ///////////////////////////////////////////////////////////////////////////////
  573. // group2 - NOT, NEG, INC, DEC, SHL, ROL, SHR, and ROR
  574. ///////////////////////////////////////////////////////////////////////////////
  575. const char* ControlUnit::ExecuteGroup2(int trace_flag)
  576. {
  577.    int SM  = (data_path.ir & 0x0c00) >> 10;
  578.    int DST = data_path.ir &0x000f;
  579.    const char*  error_message;
  580.    unsigned int dst_index;
  581.  
  582.    switch(SM) {
  583.       case REG:                     // OP Rdst
  584.         // dst < OP dst
  585.         if((error_message = op_reg_to_reg(DST)) != (void*)0)
  586.           return(error_message);
  587.  
  588.         if(trace_flag)
  589.           mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  590.         break;
  591.  
  592.       case IND:                     // OP [Rdst]
  593.         // t2 < (dst)
  594.         if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  595.           return(error_message);
  596.  
  597.         // mdr < OP t2
  598.         if((error_message = op_reg_to_mdr(T2)) != (void*)0)
  599.           return(error_message);
  600.  
  601.         // (mar) < mdr
  602.         if((error_message = mdr_to_mar_indirect()) != (void*)0)
  603.           return(error_message);
  604.  
  605.         if(trace_flag)
  606.         {
  607.           mnemonic+="[";
  608.           mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  609.           mnemonic+="]";
  610.         }
  611.         break;
  612.  
  613.       case INC:                     // OP [Rdst+]
  614.         // t2 < (dst)
  615.         if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  616.           return(error_message);
  617.  
  618.         // mdr < OP t2
  619.         if((error_message = op_reg_to_mdr(T2)) != (void*)0)
  620.           return(error_message);
  621.  
  622.         // (mar) < mdr; dst < dst + 1
  623.         if((error_message = mdr_to_mar_indirect_with_inc(DST)) != (void*)0)
  624.           return(error_message);
  625.  
  626.         if(trace_flag)
  627.         {
  628.           mnemonic+="[";
  629.           mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  630.           mnemonic+="+]";
  631.         }
  632.         break;
  633.  
  634.       case NDX:                     // OP [Rdst,index]
  635.         // t2 < (pc)
  636.         if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
  637.           return(error_message);
  638.  
  639.         // Save the index for the trace record
  640.         dst_index=data_path.register_set.GetRegister(T2);
  641.  
  642.         // mar < t2 + dst
  643.         if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
  644.           return(error_message);
  645.  
  646.         // t2 < (mar)
  647.         if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
  648.           return(error_message);
  649.  
  650.         // mdr < OP t2
  651.         if((error_message = op_reg_to_mdr(T2)) != (void*)0)
  652.           return(error_message);
  653.  
  654.         // (mar) < mdr; pc < pc + 1
  655.         if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
  656.           return(error_message);
  657.  
  658.         if(trace_flag)
  659.         {
  660.           mnemonic+="[";
  661.           mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  662.           mnemonic+=",$";
  663.           mnemonic+=IntToString(dst_index, 4);
  664.           mnemonic+="]";
  665.         }
  666.         break;
  667.    }
  668.   return((void*)0);
  669. }
  670.  
  671. ///////////////////////////////////////////////////////////////////////////////
  672. // group3 - CMP and BTST
  673. ///////////////////////////////////////////////////////////////////////////////
  674. const char* ControlUnit::ExecuteGroup3(int trace_flag)
  675. {
  676.    int DM  = (data_path.ir & 0x0300) >> 8;
  677.    int SM  = (data_path.ir & 0x0c00) >> 10;
  678.    int SRC = (data_path.ir &0x00f0) >> 4;
  679.    int DST = (data_path.ir &0x000f);
  680.    const char*  error_message;
  681.    unsigned int src_index, dst_index;
  682.  
  683.    switch(DM) {
  684.       case REG: switch(SM) {
  685.          case REG:                  // OP Rsrc,Rdst
  686.            // dst OP src
  687.            if((error_message = reg_op_reg(SRC, DST)) != (void*)0)
  688.              return(error_message);
  689.  
  690.            if(trace_flag)
  691.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  692.            break;
  693.  
  694.          case IND:                  // OP [Rsrc],Rdst
  695.            // t1 < (src)
  696.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  697.              return(error_message);
  698.  
  699.            // dst OP t1
  700.            if((error_message = reg_op_reg(T1, DST)) != (void*)0)
  701.              return(error_message);
  702.  
  703.            if(trace_flag)
  704.            {
  705.              mnemonic+="[";
  706.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  707.              mnemonic+="]";
  708.            }
  709.            break;
  710.  
  711.          case INC:                  // OP [Rsrc+],Rdst
  712.            // t1 < (src)
  713.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  714.              return(error_message);
  715.  
  716.            // src < src + 1
  717.            if((error_message = inc_reg(SRC)) != (void*)0)
  718.              return(error_message);
  719.  
  720.            // dst OP t1
  721.            if((error_message = reg_op_reg(T1, DST)) != (void*)0)
  722.              return(error_message);
  723.  
  724.            if(trace_flag)
  725.            {
  726.              mnemonic+="[";
  727.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  728.              mnemonic+="+]";
  729.            }
  730.            break;
  731.  
  732.          case NDX:                  // OP [Rsrc,index],Rdst
  733.            // t1 < (pc)
  734.            if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  735.              return(error_message);
  736.  
  737.            // Save index for trace record
  738.            src_index=data_path.register_set.GetRegister(T1);
  739.  
  740.            // pc < pc + 1
  741.            if((error_message = inc_reg(PC)) != (void*)0)
  742.              return(error_message);
  743.  
  744.            // mar < t1 + src
  745.            if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  746.              return(error_message);
  747.  
  748.            // t1 < (mar)
  749.            if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
  750.              return(error_message);
  751.  
  752.            // dst OP t1
  753.            if((error_message = reg_op_reg(T1, DST)) != (void*)0)
  754.              return(error_message);
  755.  
  756.            if(trace_flag)
  757.            {
  758.              mnemonic+="[";
  759.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  760.              mnemonic+=",$";
  761.              mnemonic+=IntToString(src_index, 4);
  762.              mnemonic+="]";
  763.            }
  764.            break;
  765.          }
  766.  
  767.          if(trace_flag)
  768.          {
  769.            mnemonic+=",";
  770.            mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  771.          }
  772.          break;
  773.  
  774.       case IND: switch (SM) {
  775.          case REG:                  // OP Rsrc,[Rdst]
  776.            // t2 < (dst)
  777.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  778.              return(error_message);
  779.  
  780.            // t2 OP src
  781.            if((error_message = reg_op_reg(SRC, T2)) != (void*)0)
  782.              return(error_message);
  783.  
  784.            if(trace_flag)
  785.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  786.            break;
  787.  
  788.          case IND:                  // OP [Rsrc],[Rdst]
  789.            // t1 < (src)
  790.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  791.              return(error_message);
  792.  
  793.            // t2 < (dst)
  794.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  795.              return(error_message);
  796.  
  797.            // t2 OP t1 
  798.            if((error_message = reg_op_reg(T1, T2)) != (void*)0)
  799.              return(error_message);
  800.  
  801.            if(trace_flag)
  802.            {
  803.              mnemonic+="[";
  804.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  805.              mnemonic+="]";
  806.            }
  807.            break;
  808.  
  809.          case INC:                  // OP [Rsrc+],[Rdst]
  810.            // t1 < (src)
  811.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  812.              return(error_message);
  813.  
  814.            // src < src + 1
  815.            if((error_message = inc_reg(SRC)) != (void*)0)
  816.              return(error_message);
  817.  
  818.            // t2 < (dst)
  819.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  820.              return(error_message);
  821.  
  822.            // t2 OP t1
  823.            if((error_message = reg_op_reg(T1, T2)) != (void*)0)
  824.              return(error_message);
  825.  
  826.            if(trace_flag)
  827.            {
  828.              mnemonic+="[";
  829.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  830.              mnemonic+="+]";
  831.            }
  832.            break;
  833.  
  834.          case NDX:                  // OP [Rsrc,index],[Rdst]
  835.            // t2 < (dst)
  836.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  837.              return(error_message);
  838.  
  839.            // t1 < (pc)
  840.            if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  841.              return(error_message);
  842.  
  843.            // Save the index for the trace record
  844.            src_index=data_path.register_set.GetRegister(T1);
  845.  
  846.            // pc < pc + 1
  847.            if((error_message = inc_reg(PC)) != (void*)0)
  848.              return(error_message);
  849.  
  850.            // mar < t1 + src 
  851.            if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  852.              return(error_message);
  853.  
  854.            // t1 < (mar)
  855.            if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
  856.              return(error_message);
  857.  
  858.            // t2 OP t1
  859.            if((error_message = reg_op_reg(T1, T2)) != (void*)0)
  860.              return(error_message);
  861.  
  862.            if(trace_flag)
  863.            {
  864.              mnemonic+="[";
  865.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  866.              mnemonic+=",$";
  867.              mnemonic+=IntToString(src_index, 4);
  868.              mnemonic+="]";
  869.            }
  870.            break;
  871.          }
  872.  
  873.          if(trace_flag)
  874.          {
  875.            mnemonic+=",[";
  876.            mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  877.            mnemonic+="]";
  878.          }
  879.          break;
  880.  
  881.       case INC: switch (SM) {
  882.          case REG:                  // OP Rsrc,[Rdst+]
  883.            // t2 < (dst)
  884.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  885.              return(error_message);
  886.  
  887.            // dst < dst + 1
  888.            if((error_message = inc_reg(DST)) != (void*)0)
  889.              return(error_message);
  890.  
  891.            // t2 OP src
  892.            if((error_message = reg_op_reg(SRC, T2)) != (void*)0)
  893.              return(error_message);
  894.  
  895.            if(trace_flag)
  896.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  897.            break;
  898.  
  899.          case IND:                  // OP [Rsrc],[Rdst+]
  900.            // t1 < (src)
  901.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  902.              return(error_message);
  903.  
  904.            // t2 < (dst)
  905.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  906.              return(error_message);
  907.  
  908.            // dst < dst + 1
  909.            if((error_message = inc_reg(DST)) != (void*)0)
  910.              return(error_message);
  911.  
  912.            // t2 OP t1
  913.            if((error_message = reg_op_reg(T1, T2)) != (void*)0)
  914.              return(error_message);
  915.  
  916.            if(trace_flag)
  917.            {
  918.              mnemonic+="[";
  919.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  920.              mnemonic+="]";
  921.            }
  922.            break;
  923.  
  924.          case INC:                  // OP [Rsrc+],[Rdst+]
  925.            // t1 < (src)
  926.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  927.              return(error_message);
  928.  
  929.            // src < src + 1
  930.            if((error_message = inc_reg(SRC)) != (void*)0)
  931.              return(error_message);
  932.  
  933.            // t2 < (dst)
  934.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  935.              return(error_message);
  936.  
  937.            // dst < dst + 1
  938.            if((error_message = inc_reg(DST)) != (void*)0)
  939.              return(error_message);
  940.  
  941.            // t2 OP t1
  942.            if((error_message = reg_op_reg(T1, T2)) != (void*)0)
  943.              return(error_message);
  944.  
  945.            if(trace_flag)
  946.            {
  947.              mnemonic+="[";
  948.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  949.              mnemonic+="+]";
  950.            }
  951.            break;
  952.  
  953.          case NDX:                  // OP [Rsrc,index],[Rdst+]
  954.            // t1 < (pc)
  955.            if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  956.              return(error_message);
  957.  
  958.            // Save the index for the trace record
  959.            src_index=data_path.register_set.GetRegister(T1);
  960.  
  961.            // pc < pc + 1
  962.            if((error_message = inc_reg(PC)) != (void*)0)
  963.              return(error_message);
  964.  
  965.            // t2 < (dst)
  966.            if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  967.              return(error_message);
  968.  
  969.            // mar < t1 + src */
  970.            if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  971.              return(error_message);
  972.  
  973.            // t1 < (mar)
  974.            if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
  975.              return(error_message);
  976.  
  977.            // dst < dst + 1
  978.            if((error_message = inc_reg(DST)) != (void*)0)
  979.              return(error_message);
  980.  
  981.            // t2 OP t1
  982.            if((error_message = reg_op_reg(T1, T2)) != (void*)0)
  983.              return(error_message);
  984.  
  985.            if(trace_flag)
  986.            {
  987.              mnemonic+="[";
  988.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  989.              mnemonic+=",$";
  990.              mnemonic+=IntToString(src_index, 4);
  991.              mnemonic+="]";
  992.            }
  993.            break;
  994.          }
  995.  
  996.          if(trace_flag)
  997.          {
  998.            mnemonic+=",[";
  999.            mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  1000.            mnemonic+="+]";
  1001.          }
  1002.          break;
  1003.  
  1004.       case NDX: switch (SM) {
  1005.          case REG:                  // OP Rsrc,[Rdst,index]
  1006.            // t2 < (pc)
  1007.            if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
  1008.              return(error_message);
  1009.  
  1010.            // Save the index for the trace record
  1011.            dst_index=data_path.register_set.GetRegister(T2);
  1012.  
  1013.            // pc < pc + 1
  1014.            if((error_message = inc_reg(PC)) != (void*)0)
  1015.              return(error_message);
  1016.  
  1017.            // mar < t2 + dst
  1018.            if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
  1019.              return(error_message);
  1020.  
  1021.            // t2 < (mar)
  1022.            if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
  1023.              return(error_message);
  1024.  
  1025.            // t2 OP src
  1026.            if((error_message = reg_op_reg(SRC, T2)) != (void*)0)
  1027.              return(error_message);
  1028.  
  1029.            if(trace_flag)
  1030.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1031.            break;
  1032.  
  1033.          case IND:                  // OP [Rsrc],[Rdst,index]
  1034.            // t1 < (src)
  1035.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  1036.              return(error_message);
  1037.  
  1038.            // t2 < (pc)
  1039.            if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
  1040.              return(error_message);
  1041.  
  1042.            // Save the index for the trace record
  1043.            dst_index=data_path.register_set.GetRegister(T2);
  1044.  
  1045.            // pc < pc + 1
  1046.            if((error_message = inc_reg(PC)) != (void*)0)
  1047.              return(error_message);
  1048.  
  1049.            // mar < t2 + dst
  1050.            if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
  1051.              return(error_message);
  1052.  
  1053.            // t2 < (mar)
  1054.            if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
  1055.              return(error_message);
  1056.  
  1057.            // t2 OP t1
  1058.            if((error_message = reg_op_reg(T1, T2)) != (void*)0)
  1059.              return(error_message);
  1060.  
  1061.            if(trace_flag)
  1062.            {
  1063.              mnemonic+="[";
  1064.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1065.              mnemonic+="]";
  1066.            }
  1067.            break;
  1068.  
  1069.          case INC:                  // OP [Rsrc+],[Rdst,index]
  1070.            // t1 < (src)
  1071.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  1072.              return(error_message);
  1073.  
  1074.            // src < src + 1
  1075.            if((error_message = inc_reg(SRC)) != (void*)0)
  1076.              return(error_message);
  1077.  
  1078.            // t2 < (pc)
  1079.            if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
  1080.              return(error_message);
  1081.  
  1082.            // Save the index for the trace record
  1083.            dst_index=data_path.register_set.GetRegister(T2);
  1084.  
  1085.            // pc < pc + 1
  1086.            if((error_message = inc_reg(PC)) != (void*)0)
  1087.              return(error_message);
  1088.  
  1089.            // mar < t2 + dst
  1090.            if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
  1091.              return(error_message);
  1092.  
  1093.            // t2 < (mar)
  1094.            if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
  1095.              return(error_message);
  1096.  
  1097.            // t2 OP t1
  1098.            if((error_message = reg_op_reg(T1, T2)) != (void*)0)
  1099.              return(error_message);
  1100.  
  1101.            if(trace_flag)
  1102.            {
  1103.              mnemonic+="[";
  1104.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1105.              mnemonic+="+]";
  1106.            }
  1107.            break;
  1108.  
  1109.          case NDX:                  // OP [Rsrc,index],[Rdst,index]
  1110.            // t1 < (pc)
  1111.            if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  1112.              return(error_message);
  1113.  
  1114.            // Save the index for the trace record
  1115.            src_index=data_path.register_set.GetRegister(T1);
  1116.  
  1117.            // pc < pc + 1
  1118.            if((error_message = inc_reg(PC)) != (void*)0)
  1119.              return(error_message);
  1120.  
  1121.            // mar < t1 + src
  1122.            if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  1123.              return(error_message);
  1124.  
  1125.            // t1 < (mar)
  1126.            if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
  1127.              return(error_message);
  1128.  
  1129.            // t2 < (pc)
  1130.            if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
  1131.              return(error_message);
  1132.  
  1133.            // Save the index for the trace record
  1134.            dst_index=data_path.register_set.GetRegister(T2);
  1135.  
  1136.            // pc < pc + 1
  1137.            if((error_message = inc_reg(PC)) != (void*)0)
  1138.              return(error_message);
  1139.  
  1140.            // mar < t2 + dst
  1141.            if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
  1142.              return(error_message);
  1143.  
  1144.            // t2 < (mar)
  1145.            if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
  1146.              return(error_message);
  1147.  
  1148.            // t2 OP t1
  1149.            if((error_message = reg_op_reg(T1, T2)) != (void*)0)
  1150.              return(error_message);
  1151.  
  1152.            if(trace_flag)
  1153.            {
  1154.              mnemonic+="[";
  1155.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1156.              mnemonic+=",$";
  1157.              mnemonic+=IntToString(src_index, 4);
  1158.              mnemonic+="]";
  1159.            }
  1160.          }
  1161.  
  1162.          if(trace_flag)
  1163.          {
  1164.            mnemonic+=",[";
  1165.            mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  1166.            mnemonic+=",$";
  1167.            mnemonic+=IntToString(dst_index, 4);
  1168.            mnemonic+="]";
  1169.          }
  1170.    }
  1171.    return((void*)0);
  1172. }
  1173.  
  1174. ///////////////////////////////////////////////////////////////////////////////
  1175. // branch - BRA
  1176. ///////////////////////////////////////////////////////////////////////////////
  1177. const char* ControlUnit::ExecuteBRA(int trace_flag)
  1178. {
  1179.    int SM  = (data_path.ir & 0x0c00) >> 10;
  1180.    int SRC = (data_path.ir &0x00f0) >> 4;
  1181.    ALUConditionCode CC = (data_path.ir &0x000f);
  1182.    const char* error_message;
  1183.    const char* cc_description; 
  1184.    unsigned int index;
  1185.  
  1186.    switch (SM) {
  1187.       case REG:                     // BRA Rsrc
  1188.         // t1 < src
  1189.         if((error_message = reg_to_reg(SRC, T1)) != (void*)0)
  1190.           return(error_message);
  1191.  
  1192.         if(data_path.alu.TestConditionCode(CC, cc_description))
  1193.         {
  1194.           // pc < t1
  1195.           if((error_message = reg_to_reg(T1, PC)) != (void*)0)
  1196.             return(error_message);
  1197.         }
  1198.         else
  1199.         {
  1200.           data_path.Clock();
  1201.         }
  1202.  
  1203.         if(trace_flag)
  1204.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1205.         break;
  1206.  
  1207.       case ABS:                     // BRA @destination
  1208.         // t1 < (pc)
  1209.         if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  1210.           return(error_message);
  1211.          
  1212.         if(data_path.alu.TestConditionCode(CC, cc_description))
  1213.         {
  1214.           // pc < t1
  1215.           if((error_message = reg_to_reg(T1, PC)) != (void*)0)
  1216.             return(error_message);
  1217.         }
  1218.         else 
  1219.         {
  1220.           // pc < pc + 1
  1221.           if((error_message = inc_reg(PC)) != (void*)0)
  1222.             return(error_message);
  1223.         }
  1224.  
  1225.         if(trace_flag)
  1226.         {
  1227.           mnemonic+="@$";
  1228.           mnemonic+=IntToString(data_path.register_set.GetRegister(T1), 4);
  1229.         }
  1230.         break;
  1231.  
  1232.       case REL:                     // BRA destination
  1233.         // t1 < (pc)
  1234.         if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  1235.           return(error_message);
  1236.  
  1237.         if(data_path.alu.TestConditionCode(CC, cc_description))
  1238.         {
  1239.           // pc < pc + t1 
  1240.           if((error_message = reg_plus_reg_to_reg(T1, PC)) != (void*)0)
  1241.             return(error_message);
  1242.         }
  1243.  
  1244.         // pc < pc + 1
  1245.         if((error_message = inc_reg(PC)) != (void*)0)
  1246.           return(error_message);
  1247.  
  1248.         if(trace_flag)
  1249.         {
  1250.           mnemonic+="$";
  1251.           mnemonic+=IntToString(data_path.register_set.GetRegister(T1), 4);
  1252.         }
  1253.         break;
  1254.  
  1255.       case NDX:                     // BRA [Rsrc,base_destination]
  1256.         // t1 < (pc)
  1257.         if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  1258.           return(error_message);
  1259.  
  1260.         // Save index for trace register
  1261.         index=data_path.register_set.GetRegister(T1);
  1262.  
  1263.         if(data_path.alu.TestConditionCode(CC, cc_description))
  1264.         {
  1265.           // t1 < t1 + src
  1266.           if((error_message = reg_plus_reg_to_reg(SRC, T1)) != (void*)0)
  1267.             return(error_message);
  1268.  
  1269.           // pc < (t1)
  1270.           if((error_message = reg_indirect_to_reg(T1, PC)) != (void*)0)
  1271.             return(error_message);
  1272.         }
  1273.         else
  1274.         {
  1275.           // pc < pc + 1
  1276.           if((error_message = inc_reg(PC)) != (void*)0)
  1277.             return(error_message);
  1278.         }
  1279.  
  1280.         if(trace_flag)
  1281.         {
  1282.           mnemonic+="[";
  1283.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1284.           mnemonic+=",$";
  1285.           mnemonic+=IntToString(index, 4);
  1286.           mnemonic+="]";
  1287.         } 
  1288.    }
  1289.  
  1290.    if(trace_flag)
  1291.    {
  1292.      mnemonic+=",";
  1293.      mnemonic+=cc_description;
  1294.    }
  1295.    return((void*)0);
  1296. }
  1297.  
  1298. ///////////////////////////////////////////////////////////////////////////////
  1299. // JSR
  1300. ///////////////////////////////////////////////////////////////////////////////
  1301. const char* ControlUnit::ExecuteJSR(int trace_flag)
  1302. {
  1303.    int SM  = (data_path.ir & 0x0c00) >> 10;
  1304.    int SRC = (data_path.ir &0x00f0) >> 4;
  1305.    ALUConditionCode CC = (data_path.ir &0x000f);
  1306.    const char* error_message;
  1307.    const char* cc_description;
  1308.    unsigned int index;
  1309.  
  1310.    switch (SM) {
  1311.       case REG:                     // JSR Rsrc
  1312.         // t1 < src
  1313.         if((error_message = reg_to_reg(SRC, T1)) != (void*)0)
  1314.           return(error_message);
  1315.  
  1316.         if(data_path.alu.TestConditionCode(CC, cc_description))
  1317.         {
  1318.           // sp < sp - 1
  1319.           if((error_message = dec_reg(SP)) != (void*)0)
  1320.             return(error_message);
  1321.  
  1322.           // (sp) < pc
  1323.           if((error_message = reg_to_reg_indirect(PC, SP)) != (void*)0)
  1324.             return(error_message);
  1325.  
  1326.           // pc < t1
  1327.           if((error_message = reg_to_reg(T1, PC)) != (void*)0)
  1328.             return(error_message);
  1329.         }
  1330.         else
  1331.         {
  1332.           data_path.Clock();
  1333.         }
  1334.  
  1335.         if(trace_flag)
  1336.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1337.         break;
  1338.  
  1339.       case ABS:                     // JSR @location
  1340.         // t1 < (pc)
  1341.         if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  1342.           return(error_message);
  1343.  
  1344.         // pc < pc + 1
  1345.         if((error_message = inc_reg(PC)) != (void*)0)
  1346.           return(error_message);
  1347.  
  1348.         if(data_path.alu.TestConditionCode(CC, cc_description))
  1349.         {
  1350.           // sp < sp - 1
  1351.           if((error_message = dec_reg(SP)) != (void*)0)
  1352.             return(error_message);
  1353.  
  1354.           // (sp) < pc
  1355.           if((error_message = reg_to_reg_indirect(PC, SP)) != (void*)0)
  1356.             return(error_message);
  1357.  
  1358.           // pc < t1
  1359.           if((error_message = reg_to_reg(T1, PC)) != (void*)0)
  1360.             return(error_message);
  1361.         }
  1362.  
  1363.         if(trace_flag)
  1364.         {
  1365.           mnemonic+="@$";
  1366.           mnemonic+=IntToString(data_path.register_set.GetRegister(T1), 4);
  1367.         }
  1368.         break;
  1369.  
  1370.       case REL:                     // JSR location
  1371.         // t1 < (pc)
  1372.         if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  1373.           return(error_message);
  1374.  
  1375.         // pc < pc + 1
  1376.         if((error_message = inc_reg(PC)) != (void*)0)
  1377.           return(error_message);
  1378.  
  1379.         if(data_path.alu.TestConditionCode(CC, cc_description))
  1380.         {
  1381.           // sp < sp - 1
  1382.           if((error_message = dec_reg(SP)) != (void*)0)
  1383.             return(error_message);
  1384.  
  1385.           // (sp) < pc
  1386.           if((error_message = reg_to_reg_indirect(PC, SP)) != (void*)0)
  1387.             return(error_message);
  1388.  
  1389.           // pc < pc + t1
  1390.           if((error_message = reg_plus_reg_to_reg(T1, PC)) != (void*)0)
  1391.             return(error_message);
  1392.         }
  1393.  
  1394.         if(trace_flag)
  1395.         {
  1396.           mnemonic+="$";
  1397.           mnemonic+=IntToString(data_path.register_set.GetRegister(T1), 4);
  1398.         }
  1399.         break;
  1400.  
  1401.       case NDX:                     // JSR [Rsrc,base_address]
  1402.         // t1 < (pc)
  1403.         if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  1404.           return(error_message);
  1405.  
  1406.         // Save index for trace register
  1407.         index=data_path.register_set.GetRegister(T1);
  1408.  
  1409.         // pc < pc + 1
  1410.         if((error_message = inc_reg(PC)) != (void*)0)
  1411.           return(error_message);
  1412.  
  1413.         if(data_path.alu.TestConditionCode(CC, cc_description))
  1414.         {
  1415.           // sp < sp - 1
  1416.           if((error_message = dec_reg(SP)) != (void*)0)
  1417.             return(error_message);
  1418.  
  1419.           // (sp) < pc
  1420.           if((error_message = reg_to_reg_indirect(PC, SP)) != (void*)0)
  1421.             return(error_message);
  1422.  
  1423.           // t1 < t1 + src
  1424.           if((error_message = reg_plus_reg_to_reg(SRC, T1)) != (void*)0)
  1425.             return(error_message);
  1426.  
  1427.           // pc < (t1)
  1428.           if((error_message = reg_indirect_to_reg(T1, PC)) != (void*)0)
  1429.             return(error_message);
  1430.         }
  1431.  
  1432.         if(trace_flag)
  1433.         {
  1434.           mnemonic+="[";
  1435.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1436.           mnemonic+=",$";
  1437.           mnemonic+=IntToString(index, 4);
  1438.           mnemonic+="]";
  1439.         } 
  1440.    }
  1441.    if(trace_flag)
  1442.    {
  1443.      mnemonic+=",";
  1444.      mnemonic+=cc_description;
  1445.    }
  1446.    return((void*)0);
  1447. }
  1448.  
  1449. ///////////////////////////////////////////////////////////////////////////////
  1450. // swap - SWAP
  1451. ///////////////////////////////////////////////////////////////////////////////
  1452. const char* ControlUnit::ExecuteSWAP(int trace_flag)
  1453. {
  1454.    int SM  = (data_path.ir & 0x0c00) >> 10;
  1455.    int SRC = (data_path.ir &0x00f0) >> 4;
  1456.    int DST = (data_path.ir &0x000f);
  1457.    const char*  error_message;
  1458.    unsigned int index;
  1459.  
  1460.    switch (SM) {
  1461.       case REG:                     // SWAP Rsrc
  1462.         // dst < *swap[src]
  1463.         if((error_message = swap_reg_to_reg(SRC, DST)) != (void*)0)
  1464.           return(error_message);
  1465.  
  1466.         if(trace_flag)
  1467.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1468.         break;
  1469.  
  1470.       case IND:                     // SWAP [Rsrc]
  1471.         // t2 < (dst)
  1472.         if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  1473.           return(error_message);
  1474.  
  1475.         // mdr < *swap[t2]
  1476.         if((error_message = swap_reg_to_mdr(T2)) != (void*)0)
  1477.           return(error_message);
  1478.  
  1479.         // (mar) < mdr
  1480.         if((error_message = mdr_to_mar_indirect()) != (void*)0)
  1481.           return(error_message);
  1482.  
  1483.         if(trace_flag)
  1484.         {
  1485.           mnemonic+="[";
  1486.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1487.           mnemonic+="]";
  1488.         }
  1489.         break;
  1490.  
  1491.       case INC:                     // SWAP [Rsrc+]
  1492.         // t2 < (dst)
  1493.         if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
  1494.           return(error_message);
  1495.  
  1496.         // mdr < *swap[t2]
  1497.         if((error_message = swap_reg_to_mdr(T2)) != (void*)0)
  1498.           return(error_message);
  1499.  
  1500.         // (mar) < mdr; dst < dst + 1
  1501.         if((error_message = mdr_to_mar_indirect_with_inc(DST)) != (void*)0)
  1502.           return(error_message);
  1503.  
  1504.         if(trace_flag)
  1505.         {
  1506.           mnemonic+="[";
  1507.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1508.           mnemonic+="+]";
  1509.         }
  1510.         break;
  1511.  
  1512.       case NDX:                     // SWAP [Rsrc,index]
  1513.         // t2 < (pc)
  1514.         if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
  1515.           return(error_message);
  1516.  
  1517.         // Save index for trace register
  1518.         index=data_path.register_set.GetRegister(T2);
  1519.  
  1520.         // mar < t2 + dst
  1521.         if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
  1522.           return(error_message);
  1523.  
  1524.         // t2 < (mar)
  1525.         if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
  1526.           return(error_message);
  1527.  
  1528.         // mdr < *swap[t2]
  1529.         if((error_message = swap_reg_to_mdr(T2)) != (void*)0)
  1530.           return(error_message);
  1531.  
  1532.         // (mar) < mdr; pc < pc + 1
  1533.         if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
  1534.           return(error_message);
  1535.  
  1536.         if(trace_flag)
  1537.         {
  1538.           mnemonic+="[";
  1539.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1540.           mnemonic+=",$";
  1541.           mnemonic+=IntToString(index, 4);
  1542.           mnemonic+="]";
  1543.         }
  1544.    }
  1545.    return((void*)0);
  1546. }
  1547.  
  1548. ///////////////////////////////////////////////////////////////////////////////
  1549. // clear - CLR
  1550. ///////////////////////////////////////////////////////////////////////////////
  1551. const char* ControlUnit::ExecuteCLR(int trace_flag)
  1552. {
  1553.    int SM  = (data_path.ir & 0x0c00) >> 10;
  1554.    int SRC = (data_path.ir &0x00f0) >> 4;
  1555.    int DST = (data_path.ir &0x000f);
  1556.    const char*  error_message;
  1557.    unsigned int index;
  1558.  
  1559.    switch (SM) {
  1560.       case REG:                     // CLR Rdst
  1561.         // dst < 0
  1562.         if((error_message = clr_reg(DST)) != (void*)0)
  1563.           return(error_message);
  1564.  
  1565.         if(trace_flag)
  1566.           mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  1567.         break;
  1568.  
  1569.       case IND:                     // CLR [Rdst]
  1570.         // t1 < 0
  1571.         if((error_message = clr_reg(T1)) != (void*)0)
  1572.           return(error_message);
  1573.  
  1574.         // (dst) < t1
  1575.         if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
  1576.           return(error_message);
  1577.  
  1578.         if(trace_flag)
  1579.         {
  1580.           mnemonic+="[";
  1581.           mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  1582.           mnemonic+="]";
  1583.         }
  1584.         break;
  1585.  
  1586.       case INC:                     // CLR [Rdst+]
  1587.         // t1 < 0 
  1588.         if((error_message = clr_reg(T1)) != (void*)0)
  1589.           return(error_message);
  1590.  
  1591.         // (dst) < t1; dst < dst + 1
  1592.         if((error_message = reg_to_reg_indirect_with_inc(T1, DST)) != (void*)0)
  1593.           return(error_message);
  1594.  
  1595.         if(trace_flag)
  1596.         {
  1597.           mnemonic+="[";
  1598.           mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  1599.           mnemonic+="+]";
  1600.         }
  1601.         break;
  1602.  
  1603.       case NDX:                     // CLR [Rdst,index]
  1604.         // mdr < 0
  1605.         if((error_message = clr_mdr()) != (void*)0)
  1606.           return(error_message);
  1607.  
  1608.         // t1 < (pc)
  1609.         if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  1610.           return(error_message);
  1611.  
  1612.         // mar < t1 + src
  1613.         if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  1614.           return(error_message);
  1615.  
  1616.         // (mar) < mdr; pc < pc + 1
  1617.         if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
  1618.           return(error_message);
  1619.  
  1620.         if(trace_flag)
  1621.         {
  1622.           mnemonic+="[";
  1623.           mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  1624.           mnemonic+=",$";
  1625.           mnemonic+=IntToString(index, 4);
  1626.           mnemonic+="]";
  1627.         }
  1628.    }
  1629.    return((void*)0);
  1630. }
  1631.  
  1632. ///////////////////////////////////////////////////////////////////////////////
  1633. // move - MOVE
  1634. ///////////////////////////////////////////////////////////////////////////////
  1635. const char* ControlUnit::ExecuteMOVE(int trace_flag)
  1636. {
  1637.    int DM  = (data_path.ir & 0x0300) >> 8;
  1638.    int SM  = (data_path.ir & 0x0c00) >> 10;
  1639.    int SRC = (data_path.ir & 0x00f0) >> 4;
  1640.    int DST = (data_path.ir & 0x000f);
  1641.    const char*  error_message;
  1642.    unsigned int src_index, dst_index;
  1643.  
  1644.    switch(DM) {
  1645.       case REG: switch(SM) {
  1646.          case REG:                  // MOVE Rsrc,Rdst
  1647.            // dst < src
  1648.            if((error_message = reg_to_reg(SRC, DST)) != (void*)0)
  1649.              return(error_message);
  1650.  
  1651.            if(trace_flag)
  1652.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1653.            break;
  1654.  
  1655.          case IND:                  // MOVE [Rsrc],Rdst
  1656.            // dst < (src)
  1657.            if((error_message = reg_indirect_to_reg(SRC, DST)) != (void*)0)
  1658.              return(error_message);
  1659.  
  1660.            if(trace_flag)
  1661.            {
  1662.              mnemonic+="[";
  1663.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1664.              mnemonic+="]";
  1665.            }
  1666.            break;
  1667.  
  1668.          case INC:                  // MOVE [Rsrc+],Rdst
  1669.            // dst < (src)
  1670.            if((error_message = reg_indirect_to_reg(SRC, DST)) != (void*)0)
  1671.              return(error_message);
  1672.  
  1673.            // src < src + 1
  1674.            if((error_message = inc_reg(SRC)) != (void*)0)
  1675.              return(error_message);
  1676.  
  1677.            if(trace_flag)
  1678.            {
  1679.              mnemonic+="[";
  1680.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1681.              mnemonic+="+]";
  1682.            }
  1683.            break;
  1684.  
  1685.          case NDX:                  // MOVE [Rsrc,index],Rdst
  1686.            // t1 < (pc)
  1687.            if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  1688.              return(error_message);
  1689.  
  1690.            // Save the index for the trace record
  1691.            src_index=data_path.register_set.GetRegister(T1);
  1692.  
  1693.            // mar < t1 + src
  1694.            if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  1695.              return(error_message);
  1696.  
  1697.            // dst < (mar)
  1698.            if((error_message = mar_indirect_to_reg(DST)) != (void*)0)
  1699.              return(error_message);
  1700.  
  1701.            // pc < pc + 1
  1702.            if((error_message = inc_reg(PC)) != (void*)0)
  1703.              return(error_message);
  1704.  
  1705.            if(trace_flag)
  1706.            {
  1707.              mnemonic+="[";
  1708.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1709.              mnemonic+=",$";
  1710.              mnemonic+=IntToString(src_index, 4);
  1711.              mnemonic+="]";
  1712.            }
  1713.          }
  1714.  
  1715.          if(trace_flag)
  1716.          {
  1717.            mnemonic+=",";
  1718.            mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  1719.          }
  1720.          break;
  1721.  
  1722.       case IND: switch (SM) {
  1723.          case REG:                  // MOVE Rsrc,[Rdst]
  1724.            // (dst) < src 
  1725.            if((error_message = reg_to_reg_indirect(SRC, DST)) != (void*)0)
  1726.              return(error_message);
  1727.  
  1728.            if(trace_flag)
  1729.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1730.            break;
  1731.  
  1732.          case IND:                  // MOVE [Rsrc],[Rdst]
  1733.            // t1 < (src)
  1734.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  1735.              return(error_message);
  1736.  
  1737.            // (dst) < t1
  1738.            if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
  1739.              return(error_message);
  1740.  
  1741.            if(trace_flag)
  1742.            {
  1743.              mnemonic+="[";
  1744.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1745.              mnemonic+="]";
  1746.            }
  1747.            break;
  1748.  
  1749.          case INC:                  // MOVE [Rsrc+],[Rdst]
  1750.            // t1 < (src)
  1751.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  1752.              return(error_message);
  1753.  
  1754.            // src < src + 1
  1755.            if((error_message = inc_reg(SRC)) != (void*)0)
  1756.              return(error_message);
  1757.  
  1758.            // (dst) < t1
  1759.            if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
  1760.              return(error_message);
  1761.  
  1762.            if(trace_flag)
  1763.            {
  1764.              mnemonic+="[";
  1765.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1766.              mnemonic+="+]";
  1767.            }
  1768.            break;
  1769.  
  1770.          case NDX:                  // MOVE [Rsrc,index],[Rdst] 
  1771.            // t1 < (pc)
  1772.            if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  1773.              return(error_message);
  1774.  
  1775.            // Save the index for the trace record
  1776.            src_index=data_path.register_set.GetRegister(T1);
  1777.  
  1778.            // pc < pc + 1
  1779.            if((error_message = inc_reg(PC)) != (void*)0)
  1780.              return(error_message);
  1781.  
  1782.            // mar < t1 + src
  1783.            if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  1784.              return(error_message);
  1785.  
  1786.            // t1 < (mar)
  1787.            if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
  1788.              return(error_message);
  1789.  
  1790.            // (dst) < t1
  1791.            if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
  1792.              return(error_message);
  1793.  
  1794.            if(trace_flag)
  1795.            {
  1796.              mnemonic+="[";
  1797.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1798.              mnemonic+=",$";
  1799.              mnemonic+=IntToString(src_index, 4);
  1800.              mnemonic+="]";
  1801.            }
  1802.          }
  1803.  
  1804.          if(trace_flag)
  1805.          {
  1806.            mnemonic+=",[";
  1807.            mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  1808.            mnemonic+="]";
  1809.          }
  1810.          break;
  1811.  
  1812.       case INC: switch (SM) {
  1813.          case REG:                  // MOVE Rsrc,[Rdst+]
  1814.            // (dst) < src; dst < dst + 1
  1815.            if((error_message=reg_to_reg_indirect_with_inc(SRC, DST))!=(void*)0)
  1816.              return(error_message);
  1817.  
  1818.            if(trace_flag)
  1819.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1820.            break;
  1821.  
  1822.          case IND:                  // MOVE [Rsrc],[Rdst+]
  1823.            // t1 < (src)
  1824.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  1825.              return(error_message);
  1826.  
  1827.            // (dst) < t1; dst < dst + 1 
  1828.            if((error_message = reg_to_reg_indirect_with_inc(T1, DST))!=(void*)0)
  1829.              return(error_message);
  1830.  
  1831.            if(trace_flag)
  1832.            {
  1833.              mnemonic+="[";
  1834.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1835.              mnemonic+="]";
  1836.            }
  1837.            break;
  1838.  
  1839.          case INC:                  // MOVE [Rsrc+],[Rdst+]
  1840.            // t1 < (src)
  1841.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  1842.              return(error_message);
  1843.  
  1844.            // src < src + 1
  1845.            if((error_message = inc_reg(SRC)) != (void*)0)
  1846.              return(error_message);
  1847.  
  1848.            // (dst) < t1; dst < dst + 1
  1849.            if((error_message=reg_to_reg_indirect_with_inc(T1, DST)) != (void*)0)
  1850.              return(error_message);
  1851.  
  1852.            if(trace_flag)
  1853.            {
  1854.              mnemonic+="[";
  1855.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1856.              mnemonic+="+]";
  1857.            }
  1858.            break;
  1859.  
  1860.          case NDX:                  // MOVE [Rsrc,index],[Rdst+]
  1861.            // t1 < (pc)
  1862.            if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  1863.              return(error_message);
  1864.  
  1865.            // Save the index for the trace record
  1866.            src_index=data_path.register_set.GetRegister(T1);
  1867.  
  1868.            // pc < pc + 1
  1869.            if((error_message = inc_reg(PC)) != (void*)0)
  1870.              return(error_message);
  1871.  
  1872.            // mar < t1 + src
  1873.            if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  1874.              return(error_message);
  1875.  
  1876.            // t1 < (mar)
  1877.            if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
  1878.              return(error_message);
  1879.  
  1880.            // (dst) < t1; dst < dst + 1
  1881.            if((error_message=reg_to_reg_indirect_with_inc(T1, DST)) != (void*)0)
  1882.              return(error_message);
  1883.  
  1884.            if(trace_flag)
  1885.            {
  1886.              mnemonic+="[";
  1887.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1888.              mnemonic+=",$";
  1889.              mnemonic+=IntToString(src_index, 4);
  1890.              mnemonic+="]";
  1891.            }
  1892.            break;
  1893.          }
  1894.  
  1895.          if(trace_flag)
  1896.          {
  1897.            mnemonic+=",[";
  1898.            mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  1899.            mnemonic+="+]";
  1900.          }
  1901.          break;
  1902.  
  1903.       case NDX: switch (SM) {
  1904.          case REG:                  // MOVE Rsrc,[Rdst,index]
  1905.            // t2 < (pc)
  1906.            if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
  1907.              return(error_message);
  1908.  
  1909.            // Save the index for the trace record
  1910.            dst_index=data_path.register_set.GetRegister(T2);
  1911.  
  1912.            // pc < pc + 1
  1913.            if((error_message = inc_reg(PC)) != (void*)0)
  1914.              return(error_message);
  1915.  
  1916.            // mar < t2 + dst
  1917.            if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
  1918.              return(error_message);
  1919.  
  1920.            // (mar) < src
  1921.            if((error_message = reg_to_mar_indirect(SRC)) != (void*)0)
  1922.              return(error_message);
  1923.  
  1924.            if(trace_flag)
  1925.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1926.            break;
  1927.  
  1928.          case IND:                  // MOVE [Rsrc],[Rdst,index]
  1929.            // t1 < (src)
  1930.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  1931.              return(error_message);
  1932.  
  1933.            // t2 < (pc)
  1934.            if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
  1935.              return(error_message);
  1936.  
  1937.            // Save the index for the trace record
  1938.            dst_index=data_path.register_set.GetRegister(T2);
  1939.  
  1940.            // pc < pc + 1
  1941.            if((error_message = inc_reg(PC)) != (void*)0)
  1942.              return(error_message);
  1943.  
  1944.            // mar < t2 + dst
  1945.            if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
  1946.              return(error_message);
  1947.  
  1948.            // (mar) < t1
  1949.            if((error_message = reg_to_mar_indirect(T1)) != (void*)0)
  1950.              return(error_message);
  1951.  
  1952.            if(trace_flag)
  1953.            {
  1954.              mnemonic+="[";
  1955.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1956.              mnemonic+="]";
  1957.            }
  1958.            break;
  1959.  
  1960.          case INC:                  // MOVE [Rsrc+],[Rdst,index]
  1961.            // t1 < (src)
  1962.            if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  1963.              return(error_message);
  1964.  
  1965.            // src < src + 1
  1966.            if((error_message = inc_reg(SRC)) != (void*)0)
  1967.              return(error_message);
  1968.  
  1969.            // t2 < (pc)
  1970.            if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
  1971.              return(error_message);
  1972.  
  1973.            // Save the index for the trace record
  1974.            dst_index=data_path.register_set.GetRegister(T2);
  1975.  
  1976.            // pc < pc + 1
  1977.            if((error_message = inc_reg(PC)) != (void*)0)
  1978.              return(error_message);
  1979.  
  1980.            // mar < t2 + dst
  1981.            if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
  1982.              return(error_message);
  1983.  
  1984.            // (mar) < t1
  1985.            if((error_message = reg_to_mar_indirect(T1)) != (void*)0)
  1986.              return(error_message);
  1987.  
  1988.            if(trace_flag)
  1989.            {
  1990.              mnemonic+="[";
  1991.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  1992.              mnemonic+="+]";
  1993.            }
  1994.            break;
  1995.  
  1996.          case NDX:                  // MOVE [Rsrc,index],[Rdst,index] 
  1997.            // t1 < (pc)
  1998.            if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  1999.              return(error_message);
  2000.  
  2001.            // Save the index for the trace record
  2002.            src_index=data_path.register_set.GetRegister(T1);
  2003.  
  2004.            // pc < pc + 1
  2005.            if((error_message = inc_reg(PC)) != (void*)0)
  2006.              return(error_message);
  2007.  
  2008.            // mar < t1 + src
  2009.            if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  2010.              return(error_message);
  2011.  
  2012.            // t1 < (mar)
  2013.            if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
  2014.              return(error_message);
  2015.  
  2016.            // t2 < (pc)
  2017.            if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
  2018.              return(error_message);
  2019.  
  2020.            // Save the index for the trace record
  2021.            dst_index=data_path.register_set.GetRegister(T2);
  2022.  
  2023.            // pc < pc + 1
  2024.            if((error_message = inc_reg(PC)) != (void*)0)
  2025.              return(error_message);
  2026.  
  2027.            // mar < t2 + dst
  2028.            if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
  2029.              return(error_message);
  2030.  
  2031.            // (mar) < t1
  2032.            if((error_message = reg_to_mar_indirect(T1)) != (void*)0)
  2033.              return(error_message);
  2034.  
  2035.            if(trace_flag)
  2036.            {
  2037.              mnemonic+="[";
  2038.              mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  2039.              mnemonic+=",$";
  2040.              mnemonic+=IntToString(src_index, 4);
  2041.              mnemonic+="]";
  2042.            }
  2043.          }
  2044.  
  2045.          if(trace_flag)
  2046.          {
  2047.            mnemonic+=",[";
  2048.            mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  2049.            mnemonic+=",$";
  2050.            mnemonic+=IntToString(dst_index, 4);
  2051.            mnemonic+="]";
  2052.          }
  2053.    }
  2054.    return((void*)0);
  2055. }
  2056.  
  2057. ///////////////////////////////////////////////////////////////////////////////
  2058. // test - TEST
  2059. ///////////////////////////////////////////////////////////////////////////////
  2060. const char* ControlUnit::ExecuteTEST(int trace_flag)
  2061. {
  2062.    int SM  = (data_path.ir & 0x0c00) >> 10;
  2063.    int SRC = (data_path.ir &0x00f0) >> 4;
  2064.    const char*  error_message;
  2065.    unsigned int index;
  2066.  
  2067.    switch (SM) {
  2068.       case REG:                     // TEST Rsrc
  2069.         // t1 < *pass[src]
  2070.         if((error_message = pass_reg_to_reg(SRC, T1)) != (void*)0)
  2071.           return(error_message);
  2072.  
  2073.         if(trace_flag)
  2074.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  2075.         break;
  2076.  
  2077.       case IND:                     // TEST [Rsrc]
  2078.         // t1 < (src)
  2079.         if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  2080.           return(error_message);
  2081.  
  2082.         // t1 < *pass[t1]
  2083.         if((error_message = pass_reg_to_reg(T1, T1)) != (void*)0)
  2084.           return(error_message);
  2085.  
  2086.         if(trace_flag)
  2087.         {
  2088.           mnemonic+="[";
  2089.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  2090.           mnemonic+="]";
  2091.         }
  2092.         break;
  2093.  
  2094.       case INC:                     // TEST [Rsrc+]
  2095.         // t1 < (src)
  2096.         if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  2097.           return(error_message);
  2098.  
  2099.         // src < src + 1
  2100.         if((error_message = inc_reg(SRC)) != (void*)0)
  2101.           return(error_message);
  2102.  
  2103.         // t1 < *pass[t1]
  2104.         if((error_message = pass_reg_to_reg(T1, T1)) != (void*)0)
  2105.           return(error_message);
  2106.  
  2107.         if(trace_flag)
  2108.         {
  2109.           mnemonic+="[";
  2110.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  2111.           mnemonic+="+]";
  2112.         }
  2113.         break;
  2114.  
  2115.       case NDX:                     // TEST [Rsrc,index]
  2116.         // t1 < (pc)
  2117.         if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  2118.           return(error_message);
  2119.  
  2120.         // Save the index for the trace record
  2121.         index=data_path.register_set.GetRegister(T1);
  2122.  
  2123.         // pc < pc + 1
  2124.         if((error_message = inc_reg(PC)) != (void*)0)
  2125.           return(error_message);
  2126.  
  2127.         // mar < t1 + src
  2128.         if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  2129.           return(error_message);
  2130.  
  2131.         // t1 < (mar)
  2132.         if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
  2133.           return(error_message);
  2134.  
  2135.         // t1 < *pass[t1]
  2136.         if((error_message = pass_reg_to_reg(T1, T1)) != (void*)0)
  2137.           return(error_message);
  2138.  
  2139.         if(trace_flag)
  2140.         {
  2141.           mnemonic+="[";
  2142.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  2143.           mnemonic+=",$";
  2144.           mnemonic+=IntToString(index, 4);
  2145.           mnemonic+="]";
  2146.         }
  2147.    }
  2148.    return((void*)0);
  2149. }
  2150.  
  2151. ///////////////////////////////////////////////////////////////////////////////
  2152. // store_flags - STF
  2153. ///////////////////////////////////////////////////////////////////////////////
  2154. const char* ControlUnit::ExecuteSTF(int trace_flag)
  2155. {
  2156.    int SM  = (data_path.ir & 0x0c00) >> 10;
  2157.    int DST = (data_path.ir &0x000f);
  2158.    const char*  error_message;
  2159.    unsigned int index;
  2160.  
  2161.    switch (SM) {
  2162.       case REG:                     // STF Rdst
  2163.         // dst < flags
  2164.         if((error_message = flags_to_reg(DST)) != (void*)0)
  2165.           return(error_message);
  2166.  
  2167.         if(trace_flag)
  2168.           mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  2169.         break;
  2170.  
  2171.       case IND:                     // STF [Rdst]
  2172.         // t1 < flags
  2173.         if((error_message = flags_to_reg(T1)) != (void*)0)
  2174.           return(error_message);
  2175.  
  2176.         // (dst) < t1
  2177.         if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
  2178.           return(error_message);
  2179.  
  2180.         if(trace_flag)
  2181.         {
  2182.           mnemonic+="[";
  2183.           mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  2184.           mnemonic+="]";
  2185.         }
  2186.         break;
  2187.  
  2188.       case INC:                     // STF [Rdst+]
  2189.         // t1 < flags
  2190.         if((error_message = flags_to_reg(T1)) != (void*)0)
  2191.           return(error_message);
  2192.  
  2193.         // (dst) < t1; dst < dst + 1
  2194.         if((error_message = reg_to_reg_indirect_with_inc(T1, DST)) != (void*)0)
  2195.           return(error_message);
  2196.  
  2197.         if(trace_flag)
  2198.         {
  2199.           mnemonic+="[";
  2200.           mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  2201.           mnemonic+="+]";
  2202.         }
  2203.         break;
  2204.  
  2205.       case NDX:                     // STF [Rdst,index]
  2206.         // mdr < flags
  2207.         if((error_message = flags_to_mdr()) != (void*)0)
  2208.           return(error_message);
  2209.  
  2210.         // t1 < (pc)
  2211.         if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  2212.           return(error_message);
  2213.  
  2214.         // Save the index to use in the trace record
  2215.         index=data_path.register_set.GetRegister(T1);
  2216.  
  2217.         // mar < t1 + src
  2218.         if((error_message = reg_plus_reg_to_mar(DST, T1)) != (void*)0)
  2219.           return(error_message);
  2220.  
  2221.         // (mar) < mdr; pc < pc + 1
  2222.         if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
  2223.           return(error_message);
  2224.  
  2225.         if(trace_flag)
  2226.         {
  2227.           mnemonic+="[";
  2228.           mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  2229.           mnemonic+=",$";
  2230.           mnemonic+=IntToString(index, 4);
  2231.           mnemonic+="]";
  2232.         }
  2233.    }
  2234.    return((void*)0);
  2235. }
  2236.  
  2237. ///////////////////////////////////////////////////////////////////////////////
  2238. // load_flags - LDF
  2239. ///////////////////////////////////////////////////////////////////////////////
  2240. const char* ControlUnit::ExecuteLDF(int trace_flag)
  2241. {
  2242.    int SM  = (data_path.ir & 0x0c00) >> 10;
  2243.    int SRC = (data_path.ir &0x00f0) >> 4;
  2244.    const char*  error_message;
  2245.    unsigned int index;
  2246.  
  2247.    switch (SM) {
  2248.       case REG:                     // LDF Rsrc
  2249.         // flags < src
  2250.         if((error_message = reg_to_flags(SRC)) != (void*)0)
  2251.           return(error_message);
  2252.  
  2253.         if(trace_flag)
  2254.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  2255.         break;
  2256.  
  2257.       case IND:                     // LDF [Rsrc]
  2258.         // t1 < (src)
  2259.         if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  2260.           return(error_message);
  2261.  
  2262.         // flags < t1
  2263.         if((error_message = reg_to_flags(T1)) != (void*)0)
  2264.           return(error_message);
  2265.  
  2266.         if(trace_flag)
  2267.         {
  2268.           mnemonic+="[";
  2269.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  2270.           mnemonic+="]";
  2271.         }
  2272.         break;
  2273.  
  2274.       case INC:                     // LDF [Rsrc+]
  2275.         // t1 < (src)
  2276.         if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  2277.           return(error_message);
  2278.  
  2279.         // src < src + 1
  2280.         if((error_message = inc_reg(SRC)) != (void*)0)
  2281.           return(error_message);
  2282.  
  2283.         // flags < t1
  2284.         if((error_message = reg_to_flags(T1)) != (void*)0)
  2285.           return(error_message);
  2286.  
  2287.         if(trace_flag)
  2288.         {
  2289.           mnemonic+="[";
  2290.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  2291.           mnemonic+="+]";
  2292.         }
  2293.         break;
  2294.  
  2295.       case NDX:                     // LDF [Rsrc,index]
  2296.         // t1 < (pc)
  2297.         if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  2298.           return(error_message);
  2299.  
  2300.         // Save the index to use in the trace record
  2301.         index=data_path.register_set.GetRegister(T1);
  2302.  
  2303.         // pc < pc + 1
  2304.         if((error_message = inc_reg(PC)) != (void*)0)
  2305.           return(error_message);
  2306.  
  2307.         // mar < t1 + src
  2308.         if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  2309.           return(error_message);
  2310.  
  2311.         // t1 < (mar)
  2312.         if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
  2313.           return(error_message);
  2314.  
  2315.         // flags < t1
  2316.         if((error_message = reg_to_flags(T1)) != (void*)0)
  2317.           return(error_message);
  2318.  
  2319.         if(trace_flag)
  2320.         {
  2321.           mnemonic+="[";
  2322.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  2323.           mnemonic+=",$";
  2324.           mnemonic+=IntToString(index, 4);
  2325.           mnemonic+="]";
  2326.         }
  2327.    }
  2328.    return((void*)0);
  2329. }
  2330.  
  2331. ///////////////////////////////////////////////////////////////////////////////
  2332. // push - PUSH
  2333. ///////////////////////////////////////////////////////////////////////////////
  2334. const char* ControlUnit::ExecutePUSH(int trace_flag)
  2335. {
  2336.    int SM  = (data_path.ir & 0x0c00) >> 10;
  2337.    int SRC = (data_path.ir & 0x00f0) >> 4;
  2338.    int DST = data_path.ir & 0x000f;
  2339.    const char*  error_message;
  2340.    unsigned int index;
  2341.  
  2342.    switch (SM) {
  2343.       case REG:                     // PUSH Rsrc
  2344.         // dst < dst - 1
  2345.         if((error_message = dec_reg(DST)) != (void*)0)
  2346.           return(error_message);
  2347.  
  2348.         // (dst) < src
  2349.         if((error_message = reg_to_reg_indirect(SRC, DST)) != (void*)0)
  2350.           return(error_message);
  2351.  
  2352.         if(trace_flag)
  2353.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  2354.         break;
  2355.  
  2356.       case IND:                     // PUSH [Rsrc]
  2357.         // dst < dst - 1
  2358.         if((error_message = dec_reg(DST)) != (void*)0)
  2359.           return(error_message);
  2360.  
  2361.         // t1 < (src)
  2362.         if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  2363.           return(error_message);
  2364.  
  2365.         // (dst) < t1
  2366.         if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
  2367.           return(error_message);
  2368.  
  2369.         if(trace_flag)
  2370.         {
  2371.           mnemonic+="[";
  2372.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  2373.           mnemonic+="]";
  2374.         }
  2375.         break;
  2376.  
  2377.       case INC:                     // PUSH [Rsrc+]
  2378.         // dst < dst - 1
  2379.         if((error_message = dec_reg(DST)) != (void*)0)
  2380.           return(error_message);
  2381.  
  2382.         // t1 < (src)
  2383.         if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
  2384.           return(error_message);
  2385.  
  2386.         // src < src + 1
  2387.         if((error_message = inc_reg(SRC)) != (void*)0)
  2388.           return(error_message);
  2389.  
  2390.         // (dst) < t1
  2391.         if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
  2392.           return(error_message);
  2393.  
  2394.         if(trace_flag)
  2395.         {
  2396.           mnemonic+="[";
  2397.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  2398.           mnemonic+="+]";
  2399.         }
  2400.         break;
  2401.  
  2402.       case NDX:                     // PUSH [Rsrc,index]
  2403.         // t1 < (pc)
  2404.         if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
  2405.           return(error_message);
  2406.  
  2407.         // Save the index to use in the trace record
  2408.         index=data_path.register_set.GetRegister(T1);
  2409.  
  2410.         // pc < pc + 1
  2411.         if((error_message = inc_reg(PC)) != (void*)0)
  2412.           return(error_message);
  2413.  
  2414.         // mar < t1 + src
  2415.         if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
  2416.           return(error_message);
  2417.  
  2418.         // t1 < (mar)
  2419.         if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
  2420.           return(error_message);
  2421.  
  2422.         // dst < dst - 1
  2423.         if((error_message = dec_reg(DST)) != (void*)0)
  2424.           return(error_message);
  2425.  
  2426.         // (dst) < t1
  2427.         if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
  2428.           return(error_message);
  2429.  
  2430.         if(trace_flag)
  2431.         {
  2432.           mnemonic+="[";
  2433.           mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
  2434.           mnemonic+=",$";
  2435.           mnemonic+=IntToString(index, 4);
  2436.           mnemonic+="]";
  2437.         }
  2438.    }
  2439.  
  2440.    if(trace_flag)
  2441.    {
  2442.      mnemonic+=",";
  2443.      mnemonic+=data_path.register_set.GetRegisterData(DST).name;
  2444.    }
  2445.    return((void*)0);
  2446. }
  2447.  
  2448. ///////////////////////////////////////////////////////////////////////////////
  2449. // set_carry - SEC 
  2450. ///////////////////////////////////////////////////////////////////////////////
  2451. const char* ControlUnit::ExecuteSEC(int trace_flag)
  2452. {
  2453.   unsigned long flag;
  2454.  
  2455.   flag = (data_path.alu.GetFlags()) | C_FLAG;
  2456.   data_path.alu.SetFlags(flag);
  2457.   return(data_path.Clock());
  2458. }
  2459.  
  2460. ///////////////////////////////////////////////////////////////////////////////
  2461. // clear_carry - CLC
  2462. ///////////////////////////////////////////////////////////////////////////////
  2463. const char* ControlUnit::ExecuteCLC(int trace_flag)
  2464. {
  2465.   unsigned long flag;
  2466.  
  2467.   flag = (data_path.alu.GetFlags()) & (~C_FLAG);
  2468.   data_path.alu.SetFlags(flag);
  2469.   return(data_path.Clock());
  2470. }
  2471.  
  2472. ///////////////////////////////////////////////////////////////////////////////
  2473. // set_interrupt - SEI
  2474. ///////////////////////////////////////////////////////////////////////////////
  2475. const char* ControlUnit::ExecuteSEI(int trace_flag)
  2476. {
  2477.   unsigned long flag;
  2478.  
  2479.   flag = (data_path.alu.GetFlags()) | I_FLAG;
  2480.   data_path.alu.SetFlags(flag);
  2481.   return(data_path.Clock());
  2482. }
  2483.  
  2484. ///////////////////////////////////////////////////////////////////////////////
  2485. // clear_interrupt - CLI
  2486. ///////////////////////////////////////////////////////////////////////////////
  2487. const char* ControlUnit::ExecuteCLI(int trace_flag)
  2488. {
  2489.   unsigned long flag;
  2490.  
  2491.   flag = (data_path.alu.GetFlags()) & (~I_FLAG);
  2492.   data_path.alu.SetFlags(flag);
  2493.   return(data_path.Clock());
  2494. }
  2495.  
  2496. ///////////////////////////////////////////////////////////////////////////////
  2497. // ret_from_int - RTI
  2498. ///////////////////////////////////////////////////////////////////////////////
  2499. const char* ControlUnit::ExecuteRTI(int trace_flag)
  2500. {
  2501.   const char* error_message;
  2502.  
  2503.   // pc < (sp)
  2504.   if((error_message = reg_indirect_to_reg(SP, PC)) != (void*)0)
  2505.     return(error_message);
  2506.  
  2507.   // sp < sp + 1
  2508.   if((error_message = inc_reg(SP)) != (void*)0)
  2509.     return(error_message);
  2510.  
  2511.   // t1 < (sp)
  2512.   if((error_message = reg_indirect_to_reg(SP, T1)) != (void*)0)
  2513.     return(error_message);
  2514.  
  2515.   // sp < sp + 1
  2516.   if((error_message = inc_reg(SP)) != (void*)0)
  2517.     return(error_message);
  2518.  
  2519.   // flags < t1
  2520.   if((error_message = reg_to_flags(T1)) != (void*)0)
  2521.     return(error_message);
  2522.  
  2523.   return((void*)0);
  2524. }
  2525.  
  2526. ///////////////////////////////////////////////////////////////////////////////
  2527. // software_int - SWI
  2528. ///////////////////////////////////////////////////////////////////////////////
  2529. const char* ControlUnit::ExecuteSWI(int trace_flag)
  2530. {
  2531.   const char* error_message;
  2532.  
  2533.   // t1 < swireg
  2534.   if((error_message = reg_to_reg(SWI, T1)) != (void*)0)
  2535.     return(error_message);
  2536.  
  2537.   // sp < sp - 1
  2538.   if((error_message = dec_reg(SP)) != (void*)0)
  2539.     return(error_message);
  2540.  
  2541.   // t2 < flags
  2542.   if((error_message = flags_to_reg(T2)) != (void*)0)
  2543.     return(error_message);
  2544.  
  2545.   // (sp) < t2; sp < sp - 1
  2546.   if((error_message = reg_to_reg_indirect_with_dec(T2, SP)) != (void*)0)
  2547.     return(error_message);
  2548.  
  2549.   // (sp) < pc
  2550.   if((error_message = reg_to_reg_indirect(PC, SP)) != (void*)0)
  2551.     return(error_message);
  2552.  
  2553.   // pc < t1
  2554.   if((error_message = reg_to_reg(T1, PC)) != (void*)0)
  2555.     return(error_message);
  2556.  
  2557.   // sei
  2558.   return(ExecuteSEI(trace_flag)); 
  2559. }
  2560.  
  2561. ///////////////////////////////////////////////////////////////////////////////
  2562. // exchange - EXCH - this instruction has not been implemented in the 
  2563. //                   simulator 
  2564. ///////////////////////////////////////////////////////////////////////////////
  2565. const char* ControlUnit::ExecuteEXCH(int trace_flag)
  2566. {
  2567.   return("Not Implemented");
  2568. }
  2569.  
  2570. ///////////////////////////////////////////////////////////////////////////////
  2571. // search - SRCH - this instruction has not been implemented in the
  2572. //                   simulator
  2573. ///////////////////////////////////////////////////////////////////////////////
  2574. const char* ControlUnit::ExecuteSRCH(int trace_flag)
  2575. {
  2576.   return("Not Implemented");
  2577. }
  2578.  
  2579.  
  2580.